
import React, { useState, useRef, useEffect, useCallback } from 'react';
import { Message, Sender } from './types';
import ChatMessage from './components/ChatMessage';
import ChatInput from './components/ChatInput';
import { BotIcon } from './components/Icons';

// @ts-ignore
const vscode = acquireVsCodeApi();

const App: React.FC = () => {
  const [messages, setMessages] = useState<Message[]>([
    {
      id: 'init',
      sender: Sender.AI,
      text: '你好，我是 软通动力 INTDOS-CodeMate。AI编程助手。随时向我提问！',
    },
  ]);
  const [isLoading, setIsLoading] = useState<boolean>(false);
  const chatContainerRef = useRef<HTMLDivElement | null>(null);

  useEffect(() => {
    // Scroll to the bottom of the chat container whenever messages change
    if (chatContainerRef.current) {
      chatContainerRef.current.scrollTop = chatContainerRef.current.scrollHeight;
    }
  }, [messages]);

  useEffect(() => {
    const handleMessage = (event: MessageEvent) => {
      const message = event.data;
      switch (message.command) {
        case 'receiveResponseChunk':
          setMessages(prev => {
            // Ensure there's a message to update and it's from the AI
            if (prev.length === 0 || prev[prev.length - 1].sender !== Sender.AI) {
              return prev;
            }

            const lastMessage = prev[prev.length - 1];
            // Create a new, updated message object instead of mutating the existing one
            const updatedLastMessage = {
              ...lastMessage,
              text: lastMessage.text + message.text
            };
            // Return a new array with the last message replaced
            return [...prev.slice(0, -1), updatedLastMessage];
          });
          break;
        case 'responseFinished':
          setIsLoading(false);
          break;
        case 'responseError':
          setMessages((prev) => {
            if (prev.length === 0 || prev[prev.length - 1].sender !== "ai" /* AI */) {
              return prev;
            }
            const lastMessage = prev[prev.length - 1];
            const updatedLastMessage = {
              ...lastMessage,
              text: `Error: ${message.error}`
            };
            return [
              ...prev.slice(0, -1),
              updatedLastMessage
            ];
          });
          setIsLoading(false);
          break;
      }
    };

    window.addEventListener('message', handleMessage);

    return () => {
      window.removeEventListener('message', handleMessage);
    };
  }, []);

  const handleSendMessage = useCallback((inputText: string) => {
    if (!inputText.trim() || isLoading) return;

    setIsLoading(true);
    const userMessage: Message = { id: Date.now().toString(), sender: Sender.User, text: inputText };
    
    // 1. The user's message and a placeholder for the AI's response are added to the state.
    const aiPlaceholder: Message = { id: (Date.now() + 1).toString(), sender: Sender.AI, text: "" };
    setMessages(prevMessages => [...prevMessages, userMessage, aiPlaceholder]);

    // 2. The history sent to the model should include the new user message but not the AI placeholder.
    const historyForApi = [...messages, userMessage];

    const ollamaMessages = historyForApi
      .filter(m => m.id !== 'init' && m.id !== 'init-error')
      .map(m => ({
        role: m.sender === Sender.AI ? 'assistant' : 'user',
        content: m.text
      }));
    
    const systemPrompt = { role: 'system', content: '你是一个专业的AI编程助手，名为INTDOS-Coder。你的回答应该精确、有帮助，并以中文进行。当提供代码时，请使用markdown代码块。' };
    
    // 3. Perform the side-effect (API call) outside of the state update.
    vscode.postMessage({
      command: 'sendPrompt',
      messages: [systemPrompt, ...ollamaMessages]
    });
  }, [isLoading, messages]);

  return (
    <div className="flex flex-col h-screen bg-slate-800 text-slate-100 font-sans">
      <header className="flex items-center p-4 border-b border-slate-700 shadow-md">
        <BotIcon className="w-6 h-6 mr-3" isThinking={isLoading} />
        <h1 className="text-xl font-semibold text-slate-200">INTDOS-Coder</h1>
      </header>

      <main ref={chatContainerRef} className="flex-1 overflow-y-auto p-4 space-y-6">
        {messages.map((msg, index) => (
          <ChatMessage 
            key={msg.id} 
            message={msg} 
            isStreaming={isLoading && index === messages.length - 1 && msg.sender === Sender.AI} 
          />
        ))}
      </main>

      <footer className="p-4 border-t border-slate-700">
        <ChatInput onSendMessage={handleSendMessage} isLoading={isLoading} />
      </footer>
    </div>
  );
};

export default App;
